{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用LS-SVMR算法建立Sepal.Length、Sepal.Width、Petal.Length对Petal.Width回归问题的支持向量机回归模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "# 准备基础数据\n",
    "iris = pd.read_csv(\"http://image.cador.cn/data/iris.csv\")\n",
    "x,y = iris.drop(columns=['Species','Petal.Width']),iris['Petal.Width']\n",
    "\n",
    "# 标准化处理\n",
    "x = x.apply(lambda v:(v-np.mean(v))/np.std(v))\n",
    "x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.33, random_state=1)\n",
    "N = x_train.shape[0]\n",
    "y_train = np.array([0]+list(y_train.values))\n",
    "\n",
    "# 设置参数sigma\n",
    "sigma = 10\n",
    "omiga = np.zeros((N,N))\n",
    "for i in range(N):\n",
    "    xi = x_train.iloc[i,:]\n",
    "    omiga[i,:] = np.exp(-np.sum((x_train - xi)**2,axis=1)/sigma**2)\n",
    "\n",
    "# 设置平衡参数gama\n",
    "gama = 10\n",
    "\n",
    "# 构建矩阵A\n",
    "A = (omiga+(1/gama)*np.identity(N))\n",
    "A = np.c_[[1]*N,A]\n",
    "A = np.r_[np.array([[0]+[1]*N]),A]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "根据估计的参数进行预测，进一步得到残差平方和"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.7705611499526341"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 求b和alpha参数\n",
    "b_alpha = np.matmul(np.linalg.inv(A),y_train)\n",
    "b = b_alpha[0]\n",
    "alpha = b_alpha[1:]\n",
    "\n",
    "# 基于 x_test 进行预测\n",
    "ypred = []\n",
    "for i in range(x_test.shape[0]):\n",
    "    xi = x_test.iloc[i,:]\n",
    "    t0 = np.exp(-np.sum((x_train - xi)**2,axis=1)/sigma**2)\n",
    "    ypred.append(np.matmul(t0,alpha)+b)\n",
    "\n",
    "# 误差平方和\n",
    "np.sum((ypred - y_test)**2)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
